package com.minicode.google;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessTokenRequest.GoogleAuthorizationCodeGrant;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAuthorizationRequestUrl;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.minicode.google.Google.GoogleDialogListener;
import com.minicode.google.util.GoogleUtil;
import com.minicode.twitter.Twitter;

public class GoogleDialog extends Dialog {
	public static final String TAG = "Google";

	static final int GO_BLUE = 0x4d78e1;
	static final float[] DIMENSIONS_LANDSCAPE = { 460, 260 };
	static final float[] DIMENSIONS_PORTRAIT = { 280, 420 };
	static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(
			ViewGroup.LayoutParams.FILL_PARENT,
			ViewGroup.LayoutParams.FILL_PARENT);
	static final int MARGIN = 4;
	static final int PADDING = 2;

	private int mIcon;
	private String mUrl;
	private GoogleDialogListener mListener;
	private ProgressDialog mSpinner;
	private WebView mWebView;
	private LinearLayout mContent;
	private TextView mTitle;
	private Handler mHandler;

	public GoogleDialog(Context context, GoogleDialogListener listener, int icon) {
		super(context);
		mListener = listener;
		mIcon = icon;
		mHandler = new Handler();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mSpinner = new ProgressDialog(getContext());
		mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
		mSpinner.setMessage("Loading...");

		mContent = new LinearLayout(getContext());
		mContent.setOrientation(LinearLayout.VERTICAL);

		setUpTitle();
		setUpWebView();

		Display display = getWindow().getWindowManager().getDefaultDisplay();
		final float scale = getContext().getResources().getDisplayMetrics().density;
		float[] dimensions = display.getWidth() < display.getHeight() ? DIMENSIONS_PORTRAIT
				: DIMENSIONS_LANDSCAPE;
		addContentView(mContent, new FrameLayout.LayoutParams(
				(int) (dimensions[0] * scale + 0.5f), (int) (dimensions[1]
						* scale + 0.5f)));
		mUrl = new GoogleAuthorizationRequestUrl(GoogleUtil.CLIENT_ID,
				GoogleUtil.REDIRECT_URI, GoogleUtil.SCOPE).build();
		retrieveRequestToken();
	}

	private void setUpTitle() {
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		Drawable icon = getContext().getResources().getDrawable(mIcon);
		mTitle = new TextView(getContext());
		mTitle.setText("Google");
		mTitle.setTextColor(Color.WHITE);
		mTitle.setTypeface(Typeface.DEFAULT_BOLD);
		mTitle.setBackgroundColor(GO_BLUE);
		mTitle.setPadding(MARGIN + PADDING, MARGIN, MARGIN, MARGIN);
		mTitle.setCompoundDrawablePadding(MARGIN + PADDING);
		mTitle.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
		mContent.addView(mTitle);
	}

	private void setUpWebView() {
		mWebView = new WebView(getContext());
		mWebView.setVerticalScrollBarEnabled(false);
		mWebView.setHorizontalScrollBarEnabled(false);
		mWebView.setWebViewClient(new GoogleDialog.GoWebViewClient());
		mWebView.getSettings().setJavaScriptEnabled(true);
		mWebView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
		mWebView.setLayoutParams(FILL);
		mContent.addView(mWebView);
	}

	private void retrieveRequestToken() {
		mSpinner.show();
		new Thread() {
			@Override
			public void run() {
				try {
					mWebView.loadUrl(mUrl);
				} catch (Exception e) {
					mListener.onError(new DialogError(e.getMessage(), -1, e
							.toString()));
				}
			}
		}.start();
	}

	private class GoWebViewClient extends WebViewClient {

		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			Log.d(TAG, "Redirect URL: " + url);
			if (url.startsWith(Twitter.CALLBACK_URI)) {
				if (url.startsWith(GoogleUtil.REDIRECT_URI)) {
					Bundle values = new Bundle();
					try {
						if (url.indexOf("code=") != -1) {

							String code = url.substring(
									GoogleUtil.REDIRECT_URI.length() + 7,
									url.length());

							AccessTokenResponse accessTokenResponse = new GoogleAuthorizationCodeGrant(
									new NetHttpTransport(),
									new JacksonFactory(), GoogleUtil.CLIENT_ID,
									GoogleUtil.CLIENT_SECRET, code,
									GoogleUtil.REDIRECT_URI).execute();

							values.putString(GoogleUtil.ACCESS_TOKEN,
									accessTokenResponse.accessToken);
							values.putLong(GoogleUtil.EXPIRATION_TIME,
									accessTokenResponse.expiresIn);
							values.putString(GoogleUtil.REFRESH_TOKEN,
									accessTokenResponse.refreshToken);
							values.putString(GoogleUtil.SCOPE_STRING,
									accessTokenResponse.scope);
							mListener.onComplete(values);
							mHandler.post(new Runnable() {
								public void run() {
									mSpinner.dismiss();
									GoogleDialog.this.dismiss();
								}
							});
						}

						// else if (url.indexOf("error=") != -1) {
						// view.setVisibility(View.INVISIBLE);
						// SharedPreferencesCredentialStore.getInstance(prefs)
						// .clearCredentials();
						// startActivity(new Intent(OAuthActivity.this,
						// GooglePlusActivity.class));
						// finish();
						// }

					} catch (Exception e) {
						// mListener.onGoogleError(new
						// GoogleError(e.toString());
						e.printStackTrace();
					}
				}
				return true;
			} else if (url.startsWith(Twitter.CANCEL_URI)) {
				mListener.onCancel();
				GoogleDialog.this.dismiss();
				return true;
			}
			getContext().startActivity(
					new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
			return true;
		}

		@Override
		public void onReceivedError(WebView view, int errorCode,
				String description, String failingUrl) {
			super.onReceivedError(view, errorCode, description, failingUrl);
			mListener.onError(new DialogError(description, errorCode,
					failingUrl));
			GoogleDialog.this.dismiss();
		}

		@SuppressWarnings("unused")
		public String convertStreamToString(InputStream is) throws IOException {
			if (is != null) {
				Writer writer = new StringWriter();

				char[] buffer = new char[1024 * 8];
				try {
					Reader reader = new BufferedReader(new InputStreamReader(
							is, "UTF-8"));
					int n;
					while ((n = reader.read(buffer)) != -1) {
						writer.write(buffer, 0, n);
					}
				} finally {
					is.close();
				}
				return writer.toString();
			} else {
				return "";
			}
		}

		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {

			Log.d(TAG, "WebView loading URL: " + url);

			super.onPageStarted(view, url, favicon);
			if (mSpinner.isShowing()) {
				mSpinner.dismiss();
			}
			mSpinner.show();
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			super.onPageFinished(view, url);

			if (url.startsWith(GoogleUtil.REDIRECT_URI)) {
				Bundle values = new Bundle();
				try {
					if (url.indexOf("code=") != -1) {

						String code = url.substring(
								GoogleUtil.REDIRECT_URI.length() + 7,
								url.length());

						AccessTokenResponse accessTokenResponse = new GoogleAuthorizationCodeGrant(
								new NetHttpTransport(), new JacksonFactory(),
								GoogleUtil.CLIENT_ID, GoogleUtil.CLIENT_SECRET,
								code, GoogleUtil.REDIRECT_URI).execute();

						values.putString(GoogleUtil.ACCESS_TOKEN,
								accessTokenResponse.accessToken);
						values.putLong(GoogleUtil.EXPIRATION_TIME,
								accessTokenResponse.expiresIn);
						values.putString(GoogleUtil.REFRESH_TOKEN,
								accessTokenResponse.refreshToken);
						values.putString(GoogleUtil.SCOPE_STRING,
								accessTokenResponse.scope);
						mListener.onComplete(values);
						mHandler.post(new Runnable() {
							public void run() {
								mSpinner.dismiss();
								GoogleDialog.this.dismiss();
							}
						});
					}

					// else if (url.indexOf("error=") != -1) {
					// view.setVisibility(View.INVISIBLE);
					// SharedPreferencesCredentialStore.getInstance(prefs)
					// .clearCredentials();
					// startActivity(new Intent(OAuthActivity.this,
					// GooglePlusActivity.class));
					// finish();
					// }

				} catch (Exception e) {
					// mListener.onGoogleError(new GoogleError(e.toString());
					e.printStackTrace();
				}
			}

			String title = mWebView.getTitle();
			if (title != null && title.length() > 0) {
				mTitle.setText(title);
			}
			mSpinner.dismiss();
		}
	}

	class MyJavaScriptInterface {
		public void showHTML(String html) {
		}
	}

}